package com.hksj.jetlinks.service;

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hksj.common.config.cache.RedisCache;
import com.hksj.jetlinks.model.LoginUser;
import com.hksj.jetlinks.model.SimpleUserToken;
import com.hksj.jetlinks.constant.AuthConstants;
import com.hksj.jetlinks.entity.User;
import com.hksj.jetlinks.mapper.JetUserMapper;
import com.hksj.jetlinks.vo.ButtonVO;
import com.hksj.jetlinks.vo.MenuVO;
import com.hksj.jetlinks.vo.RoleVO;
import com.hksj.jetlinks.vo.UserDetailVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户信息 服务类
 * @author chenxingqing
 */
@Service
public class JetUserService extends ServiceImpl<JetUserMapper, User> {
    @Autowired
    private RedisCache<LoginUser> loginUserRedisCache;

    @Autowired
    private RedisCache<String> jetTokenRedisCache;

    public LoginUser getLoginUserWithCache(SimpleUserToken simpleUserToken){
        String jetToken = jetTokenRedisCache.getCacheObject(getJetTokenRedisKey(simpleUserToken.getUserId()));
        if (ObjectUtils.isEmpty(jetToken)){
            jetTokenRedisCache.setCacheObject(getJetTokenRedisKey(simpleUserToken.getUserId()),simpleUserToken.getToken());
        }else{
            if (!Objects.equals(jetToken,simpleUserToken.getToken())){
                loginUserRedisCache.deleteObject(getJetLoginUserRedisKey(jetToken));
                jetTokenRedisCache.setCacheObject(getJetTokenRedisKey(simpleUserToken.getUserId()),simpleUserToken.getToken());
            }
        }
        LoginUser loginUser = loginUserRedisCache.getCacheObject(getJetLoginUserRedisKey(simpleUserToken.getToken()));
        if (ObjectUtils.isEmpty(loginUser)){
            loginUser = getLoginUser(simpleUserToken);
            loginUserRedisCache.setCacheObject(getJetLoginUserRedisKey(simpleUserToken.getToken()),loginUser);
        }
        return loginUser;
    }

    public LoginUser getLoginUser(SimpleUserToken simpleUserToken) {
        User jetUser = getById(simpleUserToken.getUserId());
        jetUser.setPassword(null);
        jetUser.setSalt(null);
        simpleUserToken.setUserType(jetUser.getType());

        Set<String> menuSet = new HashSet<>();
        Set<String> roleSet = new HashSet<>();
        List<RoleVO> roles = listUserRole(simpleUserToken);
        if (!ObjectUtils.isEmpty(roles)){
            for (RoleVO role : roles) {
                roleSet.add(role.getCode());
            }
        }

        List<MenuVO> menus = listUserMenu(simpleUserToken);
        if (!ObjectUtils.isEmpty(menus)){
            for (MenuVO menu : menus) {
                menuSet.add(menu.getCode());
                if (!ObjectUtils.isEmpty(menu.getButtons())){
                    List<ButtonVO> buttons = JSONArray.parseArray(menu.getButtons(), ButtonVO.class);
                    if (!ObjectUtils.isEmpty(buttons)){
                        for (ButtonVO button : buttons) {
                            menuSet.add(menu.getCode() + ":" + button.getId());
                        }
                    }
                }
            }
        }
        return new LoginUser(jetUser,menuSet.stream().collect(Collectors.toList()) ,roleSet.stream().collect(Collectors.toList()), 1);
    }

    private List<MenuVO> listUserMenu(SimpleUserToken simpleUserToken) {
        if (AuthConstants.ADMIN.equals(simpleUserToken.getUserType())){
            List<MenuVO> menus = listAllMenu();
            return menus;
        }
        return listUserMenu(simpleUserToken.getUserId());
    }

    private List<RoleVO> listUserRole(SimpleUserToken simpleUserToken) {
        if (AuthConstants.ADMIN.equals(simpleUserToken.getUserType())){
            RoleVO roleVO = new RoleVO();
            roleVO.setId(AuthConstants.ADMIN);
            roleVO.setName(AuthConstants.ADMIN);
            roleVO.setCode(AuthConstants.ADMIN);
            roleVO.setStatus("enabled");
            return Arrays.asList(roleVO);
        }
        return listUserRole(simpleUserToken.getUserId());
    }

    private List<MenuVO> listAllMenu() {
        return baseMapper.listAllMenu();
    }

    private List<MenuVO> listUserMenu(String userId) {
        return baseMapper.listUserMenu(userId);
    }

    private List<RoleVO> listUserRole(String userId) {
        return baseMapper.listUserRole(userId);
    }

    private String getJetLoginUserRedisKey(String key) {
        return AuthConstants.CACHE_KEY_JET_LOGIN_USER.concat(key);
    }

    private String getJetTokenRedisKey(String key) {
        return AuthConstants.CACHE_KEY_JET_USER_TOKEN.concat(key);
    }

    public UserDetailVO getUserDetail(String userId) {
        return baseMapper.getUserDetail(userId);
    }

    public void updatePhoneNumber(String userId, String phoneNumber) {
        baseMapper.updatePhoneNumber(userId,phoneNumber);
    }
}
